package log720.lab1;

import org.omg.CosNaming.*;
//import log720.lab1.GridException;

public class VoitureClient {
	private static BufferedReader br = new BufferedReader(new FileReader(args[i]));
	
	public static void main(String args[]) {
		try {
			BanqueReactions banqueReactions;
			BanqueInfractions banqueInfractions;

			// Initialisation CORBA
			org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null);

			if (args.length == 2) {
				// args[0] is an IOR-string
				banqueReactions = BanqueReactionsHelper.narrow(orb.string_to_object(args[0]));
				banqueInfractions = BanqueInfractionsHelper.narrow(orb.string_to_object(args[1]));
			} else {
				NamingContextExt nc = NamingContextExtHelper.narrow(orb
						.resolve_initial_references("NameService"));

				// nc.to_name("grid.example");

				org.omg.CORBA.Object o = nc.resolve(nc.to_name("log720.lab1"));

				banqueReactions = BanqueReactionsHelper.narrow(o);
				banqueInfractions = BanqueInfractionsHelper.narrow(o);
			}
			
			// Initialisation des variables locales
			String optionChoisie = "";
			
			// Affichage du menu principal et choix de l'option par l'utilisateur
			while (!optionChoisie.toLowerCase().equals("x")){
				System.out.println("\nMENU PRINCIPAL");
				System.out.println("===========================================");
				System.out.println("1. Obtenir la liste des réactions possibles");
				System.out.println("2. Ajouter une réaction au dossier sélectionné");
				System.out.println("3. Ajouter une réaction à la banque de réactions");
				System.out.println("4. Obtenir une liste de dossiers");
				System.out.println("5. Visualiser un dossier");
				System.out.println("6. Obtenir la liste d'infractions possibles");
				System.out.println("7. Ajouter une infraction ");
				System.out.println("X. Quitter");
				System.out.print("Veuillez entrer votre choix: ");
				
				optionChoisie = br.readLine();
				System.out.println(""); // On ajoute un saut de ligne après pour la lisibilité
				
				if(optionChoisie.equals("1")){
					obtenirListeReactions(banqueReactions);
				} else if(optionChoisie.equals("2")){
					ajouterReactionDossier();
				} else if(optionChoisie.equals("3")){
					ajouterReactionBanque();
				} else if(optionChoisie.equals("4")){
					obtenirListeDossiers();
				} else if(optionChoisie.equals("5")){
					visualiserDossier();
				} else if(optionChoisie.equals("6")){
					obtenirListeInfractions(banqueInfractions);
				} else if(optionChoisie.equals("7")){
					ajouterInfractionDossier();
				} 
			}

			orb.shutdown(true);
			System.out.println("done. ");

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Procédure servant à afficher la liste des réactions possibles.
	 */
	private void obtenirListeReactions(BanqueReactions banqueReactions){
		// On va chercher la liste des réactions dans la banque
		CollectionReactions listeReactions = banqueReactions.getReactions();
		
		// On affiche la liste des réactions trouvées
		if (listeReactions.getSize() == 0){
			System.out.println("\nAucune réaction présentement dans la banque de réactions\n");
		} else {
			afficherReactions(listeReactions);
		}
	}
	
	/**
	 * Procédure servant à ajouter une réaction à un dossier sélectionné.
	 * Elle demande d'abord à l'utilisateur de sélectionner un dossier, puis
	 * la réaction à ajouter.
	 */
	private void ajouterReactionDossier(){
		String entreeUtilisateur = "";
		long idDossier = -1;
		long idReaction = -1;
		
		// On demande à l'utilisateur l'id du dossier et de la réaction désirée
		System.out.print("\nVeuillez entrer l'id du dossier désiré: ");
		entreeUtilisateur = br.readLine();
		idDossier = Long.valueOf(entreeUtilisateur).longValue();
		
		// ?AJOUTER DE LA VALIDATION DE STRING (doit être un entier)?
		
		// On valide si le dossier existe
		if (trouverDossierParId(idDossier) != null) {
			// Si le dossier existe, on demande l'id de la réaction à ajouter
			System.out.print("\nVeuillez entrer l'id de la réaction à ajouter: ");
			entreeUtilisateur = br.readLine();
			idReaction = Long.valueOf(entreeUtilisateur).longValue();
			
			// ?AJOUTER DE LA VALIDATION DE STRING (doit être un entier)?
			
			// On valide si la réaction existe
			if (trouverReactionParId(idReaction) != null) {
				// On ajoute la réaction au dossier
				ajouterReactionAuDossier(idDossier, idReaction);
				System.out.println("La réaction a été ajoutée au dossier.");
			} else {
				System.out.println("La réaction entrée n'a pas été trouvée.");
			}
		} else {
			System.out.println("Le dossier entré n'a pas été trouvé.");
		}
	}
	
	/**
	 * Procédure servant à ajouter une réaction à la banque de réactions. Une réaction possède les 
	 * informations suivantes:
	 * - Le nom de la réaction
	 * - La gravité de la réaction
	 */
	private void ajouterReactionBanque(){
		String entreeUtilisateur = "";
		long gravite = -1;
		String reaction = "";
		
		// On demande à l'utilisateur la réaction à ajouter ainsi que sa gravité
		System.out.print("\nVeuillez entrer le nom de la réaction à ajouter: ");
		reaction = br.readLine();
		
		System.out.print("\nVeuillez entrer la gravité de la réaction: ");
		entreeUtilisateur = br.readLine();
		gravite = Long.valueOf(entreeUtilisateur).longValue();
		// ?AJOUTER DE LA VALIDATION DE STRING (doit être un entier)?
		
		// On ajoute la réaction à la banque de réactions
		ajouterReaction(reaction, gravite);
		System.out.println("La réaction a été ajoutée à la banque de réactions.\n");		
	}
	
	/**
	 * Procédure servant à afficher une liste de dossiers selon le nom et prénom,
	 * numéro de plaque ou numéro de permis. La procédure s'occupe de demander à 
	 * l'utilisateur quelle liste afficher.
	 */
	private void obtenirListeDossiers(){
		// Initialisation des variables locales
		String optionChoisie = "";
		CollectionDossier dossiersTrouves;
		Dossier dossierCourant;
		
		// Affichage du menu principal et choix de l'option par l'utilisateur
		System.out.println("Type de recherche de dossier");
		System.out.println("===========================================");
		System.out.println("Obtenir la liste de dossiers selon: ");
		System.out.println("1. Le nom et le prénom");
		System.out.println("2. Le numéro de plaque");
		System.out.println("3. Le numéro de permis");
		System.out.print("Veuillez entrer l'option désirée: ");
		
		optionChoisie = br.readLine();
		System.out.println(""); // On ajoute un saut de ligne après pour la lisibilité
		
		if(optionChoisie.equals("1")){
			// Recherche de dossier par nom et prénom
			String nom = "";
			String prenom = "";
			
			// On demande le prénom et le nom à l'utilisateur
			System.out.print("\nVeuillez entrer le prénom: ");
			prenom = br.readLine();
			System.out.println(""); // On ajoute un saut de ligne après pour la lisibilité
			
			System.out.print("\nVeuillez entrer le nom: ");
			nom = br.readLine();
			System.out.println(""); // On ajoute un saut de ligne après pour la lisibilité
			
			// On effectue la recherche de dossiers
			dossiersTrouves = trouverDossiersParNom(nom, prenom);
		} else if(optionChoisie.equals("2")){
			// Recherche de dossier par numéro de plaque
			String noPlaque = "";
			
			// On demande le numéro de plaque à l'utilisateur
			System.out.print("\nVeuillez entrer le numéro de plaque: ");
			noPlaque = br.readLine();
			System.out.println(""); // On ajoute un saut de ligne après pour la lisibilité
			
			// On effectue la recherche de dossiers
			dossiersTrouves = trouverDossiersParPlaque(noPlaque);
		} else if(optionChoisie.equals("3")){
			// Recherche de dossier par numéro de permis
			String noPermis = "";
			
			// On demande le numéro de permis à l'utilisateur
			System.out.print("\nVeuillez entrer le numéro de permis: ");
			numPermis = br.readLine();
			System.out.println(""); // On ajoute un saut de ligne après pour la lisibilité
			
			// On effectue la recherche de dossiers
			dossiersTrouves = trouverDossierParPermis(noPermis);
		} 
		
		// On vérifie s'il y a eu une recherche de dossiers (option 1, 2 ou 3)
		if (dossiersTrouves != null) {
			// Si des dossiers ont été trouvés, on les affiches, sinon on affiche un message correspondant
			if (dossiersTrouves.getSize() != 0){
				System.out.print("\nVoici la liste des dossiers trouvés"
							+ "(numéro de permis, prénom, nom, numéro de plaque, niveau):");
				for (int i = 0; i < dossiersTrouves.getSize(); i++){
					dossierCourant = dossiersTrouves.getDossier(i);
					System.out.println(" - " + dossierCourant.getNoPermis + ",\t" 
											 + dossierCourant.getPrenom + ",\t" 
											 + dossierCourant.getNom + ",\t" 
											 + dossierCourant.getNoPlaque + ",\t" 
											 + dossierCourant.getNiveau);	
				}
			} else {
				System.out.println("\nAucun dossiers trouvé par cette recherche.\n");
			}
		}
	}
	
	/**
	 * Procédure servant à afficher le contenu d'un dossier. Elle demande donc à
	 * l'utilisateur quel dossier afficher.
	 */
	private void visualiserDossier(){
		String entreeUtilisateur = "";
		long idDossier = -1;
		Dossier dossierCourant;
		
		// On demande à l'utilisateur l'id du dossier désiré
		System.out.print("\nVeuillez entrer l'id du dossier désiré: ");
		entreeUtilisateur = br.readLine();
		idDossier = Long.valueOf(entreeUtilisateur).longValue();
		
		// ?AJOUTER DE LA VALIDATION DE STRING (doit être un entier)?
		
		// On va chercher le dossier dans la banque de dossiers
		dossierCourant = trouverDossierParId(idDossier);
		
		// On valide si le dossier existe
		if (dossierCourant != null) {
			// Si le dossier existe, on affiche ses informations
			
			// ?AJOUTER DE LA VALIDATION DE STRING (doit être un entier)?
			// On affiche les informations de base
			System.out.println("Voici les informations sur le dossier: ");			
			System.out.println(" - ID: " + dossierCourant.getId());			
			System.out.println(" - Nom: " + dossierCourant.getNom());			
			System.out.println(" - Prénom: "  + dossierCourant.getPrenom());			
			System.out.println(" - Numéro de permis: "  + dossierCourant.getNoPermis());			
			System.out.println(" - Numéro de plaque: "  + dossierCourant.getNoPlaque());			
			System.out.println(" - Niveau: "  + dossierCourant.getNiveau() + "\n");
			
			// On affiche les informations sur les infractions associées au dossier
			System.out.println("Voici la liste des infractions associées au dossier: ");	
			afficherInfractions(dossierCourant.getListeInfraction());
			
			// On affiche les informations sur les réactions associées au dossier
			System.out.println("Voici la liste des réactions associées au dossier: ");
			afficherReactions(dossierCourant.getListeReaction());
		} else {
			System.out.println("Le dossier entré n'a pas été trouvé.");
		}
	}
	
	/**
	 * Procédure servant à afficher la liste des infractions possibles.
	 */
	private void obtenirListeInfractions(BanqueInfractions banqueInfractions){
		// On va chercher la liste des infractions dans la banque
		CollectionInfractions listeInfractions = banqueInfractions.getInfractions();
		
		// On affiche la liste des infractions trouvées
		if (listeInfractions.getSize() == 0){
			System.out.println("\nAucune infraction présentement dans la banque d'infractions\n");
		} else {
			afficherInfractions(listeInfractions);
		}
	}
	
	/**
	 * Procédure servant à ajouter une infraction à un dossier sélectionné.
	 * Elle demande d'abord à l'utilisateur de sélectionner un dossier, puis
	 * l'infraction à ajouter.
	 */
	private void ajouterInfractionDossier(){
		String entreeUtilisateur = "";
		long idDossier = -1;
		long idInfraction = -1;
		
		// On demande à l'utilisateur l'id du dossier et de l'infraction désirée
		System.out.print("\nVeuillez entrer l'id du dossier désiré: ");
		entreeUtilisateur = br.readLine();
		idDossier = Long.valueOf(entreeUtilisateur).longValue();
		
		// ?AJOUTER DE LA VALIDATION DE STRING (doit être un entier)?
		
		// On valide si le dossier existe
		if (trouverDossierParId(idDossier) != null) {
			// Si le dossier existe, on demande l'id de l'infraction à ajouter
			System.out.print("\nVeuillez entrer l'id de l'infraction à ajouter: ");
			entreeUtilisateur = br.readLine();
			idInfraction = Long.valueOf(entreeUtilisateur).longValue();
			
			// ?AJOUTER DE LA VALIDATION DE STRING (doit être un entier)?
			
			// On valide si l'infraction existe
			if (trouverInfractionParId(idInfraction) != null) {
				// On ajoute l'infraction au dossier
				ajouterReactionAuDossier(idDossier, idInfraction);
				System.out.println("L'infraction a été ajoutée au dossier.");
			} else {
				System.out.println("L'infraction entrée n'a pas été trouvée.");
			}
		} else {
			System.out.println("Le dossier entré n'a pas été trouvé.");
		}
	}
	
	/**
	 * Procédure servant à afficher les réactions contenues dans une collection de réactions.
	 */
	private void afficherReactions(CollectionReactions listeReactions){
		Reaction reactionCourante;
		
		// On passe à travers la liste des dossiers de la banque de dossiers
		for (int i = 0; i < listeReactions.getSize(); i++){
			reactionCourante = listeReactions.getReaction(i);
			System.out.println(" - " + reactionCourante.getId + ",\t" 
									 + reactionCourante.getDescription + ",\t" 
									 + reactionCourante.getNiveau);	
		}
	}
	
	/**
	 * Procédure servant à afficher les infractions contenues dans une collection de réactions.
	 */
	private void afficherInfractions(CollectionInfractions listeInfractions){
		Infraction infractionCourante;
		
		// On passe à travers la liste des dossiers de la banque de dossiers
		for (int i = 0; i < listeInfractions.getSize(); i++){
			infractionCourante = listeInfractions.getInfractions(i);
			System.out.println(" - " + infractionCourante.getId + ",\t" 
									 + infractionCourante.getDescription + ",\t" 
									 + infractionCourante.getNiveau);	
		}
	}
}
